# CMakeLists.txt for RSUMonitor project
cmake_minimum_required(VERSION 3.10)

# # 设置 C 编译器（如果不指定版本的话，使用的是 gcc 的默认版本）
# set (CMAKE_C_COMPILER /home/aston/work/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc)
# # # 设置 C++ 编译器 (指定的编译器为 g++9 )
# set (CMAKE_CXX_COMPILER /home/aston/work/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++)

set(VCPKG_ROOT "/home/aston/work/MEC_code/vcpkg/scripts/buildsystems/vcpkg.cmake") #设置使用vcpkg的路径
set(CMAKE_TOOLCHAIN_FILE ${VCPKG_ROOT})
# set(VCPKG_TARGET_TRIPLET "x64-linux")
# 根据vcpkg.cmake 中的配置编译平台
# set(VCPKG_TARGET_TRIPLET "arm64-linux") 
set(CMAKE_BUILD_TYPE "Release")
set(FBCONV_BUILD_JNI  false)

project(RSUMonitor VERSION 1.0 LANGUAGES CXX C)

if(NOT TARGET nlohmann_json)
  find_package(nlohmann_json CONFIG REQUIRED)
endif()

if(NOT TARGET Protobuf)
  find_package(Protobuf CONFIG REQUIRED)
endif()


# if(NOT TARGET PahoMqttCpp)
#   find_package(PahoMqttCpp CONFIG REQUIRED)
# endif()

find_package(PahoMqttCpp CONFIG REQUIRED)



# 设置C++标准
set(CMAKE_CXX_STANDARD 11 )
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 设置输出目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

# 添加源文件目录
include_directories(${CMAKE_SOURCE_DIR}/src)


# 设置libpcap路径
set(PCAP_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_part/src/pcap")
set(PCAP_INCLUDE_DIR "${PCAP_ROOT_DIR}/inc")

# 允许通过命令行强制指定架构
# 使用方法: cmake -DFORCE_ARCH=arm 或 cmake -DFORCE_ARCH=x86
set(FORCE_ARCH "" CACHE STRING "Force architecture (arm or x86)")

# 检测目标架构
if(FORCE_ARCH)
    if(FORCE_ARCH STREQUAL "arm")
        set(PCAP_LIB_DIR "${PCAP_ROOT_DIR}/lib/arm")
        message(STATUS "Forced ARM architecture via FORCE_ARCH")
    elseif(FORCE_ARCH STREQUAL "x86")
        set(PCAP_LIB_DIR "${PCAP_ROOT_DIR}/lib/x86")
        message(STATUS "Forced x86 architecture via FORCE_ARCH")
    else()
        message(WARNING "Unknown FORCE_ARCH value: ${FORCE_ARCH}, defaulting to auto-detection")
        # 继续使用自动检测
        if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm.*|ARM.*|aarch64.*|AARCH64.*")
            set(PCAP_LIB_DIR "${PCAP_ROOT_DIR}/lib/arm")
            message(STATUS "Building for ARM architecture")
        elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|i386|i686")
            set(PCAP_LIB_DIR "${PCAP_ROOT_DIR}/lib/x86")
            message(STATUS "Building for x86 architecture")
        else()
            # 默认使用x86
            set(PCAP_LIB_DIR "${PCAP_ROOT_DIR}/lib/x86")
            message(WARNING "Unknown architecture, defaulting to x86")
        endif()
    endif()
else()
    # 自动检测架构
    if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm.*|ARM.*|aarch64.*|AARCH64.*")
        set(PCAP_LIB_DIR "${PCAP_ROOT_DIR}/lib/arm")
        message(STATUS "Building for ARM architecture")
    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|i386|i686")
        set(PCAP_LIB_DIR "${PCAP_ROOT_DIR}/lib/x86")
        message(STATUS "Building for x86 architecture")
    else()
        # 默认使用x86
        set(PCAP_LIB_DIR "${PCAP_ROOT_DIR}/lib/x86")
        message(WARNING "Unknown architecture, defaulting to x86")
    endif()
endif()

# 添加包含目录
include_directories(${PCAP_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/inc) 

# 添加ASN.1编解码库
include_directories(${CMAKE_SOURCE_DIR}/DayII2020ZBMEC)
file(GLOB ASN1_SOURCES ${CMAKE_SOURCE_DIR}/DayII2020ZBMEC/*.c)
# 从所有源文件中移除排除的文件
list(REMOVE_ITEM ASN1_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/DayII2020ZBMEC/converter-example.c)

protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS proto/nebulalink.perceptron.proto)

# 查找libpcap库
find_library(PCAP_LIBRARY
    NAMES pcap libpcap
    PATHS ${PCAP_LIB_DIR}
    NO_DEFAULT_PATH
)
if(NOT PCAP_LIBRARY)
    message(FATAL_ERROR "libpcap library not found in ${PCAP_LIB_DIR}")
endif()

message(STATUS "Found libpcap: ${PCAP_LIBRARY}")

# 添加项目源文件
file(GLOB PROJECT_SOURCES 
    ${CMAKE_SOURCE_DIR}/src/*.cpp
)

# 创建可执行文件
add_executable(RSUMonitor ${PROJECT_SOURCES} ${ASN1_SOURCES} ${PROTO_SRCS})

# 链接库
target_link_libraries(RSUMonitor ${PCAP_LIBRARIES} ${PCAP_LIBRARY} nlohmann_json
            nlohmann_json::nlohmann_json
            protobuf::libprotoc
            protobuf::libprotobuf
            protobuf::libprotobuf-lite 
            PahoMqttCpp::paho-mqttpp3-static )

# 添加线程库
find_package(Threads REQUIRED)
target_link_libraries(RSUMonitor ${CMAKE_THREAD_LIBS_INIT} )

# 安装规则
install(TARGETS RSUMonitor DESTINATION bin)
install(FILES ${CMAKE_SOURCE_DIR}/config.ini DESTINATION bin OPTIONAL)

# 添加测试
enable_testing()

# 打印配置信息
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "C++ compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")

# 复制pcap文件到输出目录
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/all.pcap ${CMAKE_BINARY_DIR}/bin/all.pcap COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.ini ${CMAKE_BINARY_DIR}/bin/config.ini COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/run.sh ${CMAKE_BINARY_DIR}/bin/run.sh COPYONLY)

# 根据FORCE_ARCH宏动态拷贝pcap库到bin/lib目录
if(FORCE_ARCH)
    if(FORCE_ARCH STREQUAL "arm")
        # 拷贝ARM版本的pcap库到bin/lib
        file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/third_part/src/pcap/lib/arm/ DESTINATION ${CMAKE_BINARY_DIR}/bin/lib)
        message(STATUS "Copying ARM pcap libraries to bin/lib")
    elseif(FORCE_ARCH STREQUAL "x86")
        # 拷贝x86版本的pcap库到bin/lib
        file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/third_part/src/pcap/lib/x86/ DESTINATION ${CMAKE_BINARY_DIR}/bin/lib)
        message(STATUS "Copying x86 pcap libraries to bin/lib")
    else()
        # 默认拷贝x86版本
        file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/third_part/src/pcap/lib/x86/ DESTINATION ${CMAKE_BINARY_DIR}/bin/lib)
        message(STATUS "Copying default x86 pcap libraries to bin/lib")
    endif()
else()
    # 根据自动检测的架构拷贝对应版本
    if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm.*|ARM.*|aarch64.*|AARCH64.*")
        file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/third_part/src/pcap/lib/arm/ DESTINATION ${CMAKE_BINARY_DIR}/bin/lib)
        message(STATUS "Auto-detected ARM: Copying ARM pcap libraries to bin/lib")
    else()
        file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/third_part/src/pcap/lib/x86/ DESTINATION ${CMAKE_BINARY_DIR}/bin/lib)
        message(STATUS "Auto-detected x86: Copying x86 pcap libraries to bin/lib")
    endif()
endif()



# 创建打包目标，将bin和lib目录打包成tar文件
add_custom_target(package
    COMMAND ${CMAKE_COMMAND} -E echo "Creating package directory..."
    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/${PROJECT_NAME}
    COMMAND ${CMAKE_COMMAND} -E echo "Copying bin directory..."
    COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/bin ${CMAKE_BINARY_DIR}/${PROJECT_NAME}
    COMMAND ${CMAKE_COMMAND} -E echo "Copying lib directory..."
    COMMAND ${CMAKE_COMMAND} -E tar czf ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.tar.gz  ${CMAKE_BINARY_DIR}/${PROJECT_NAME}
    COMMAND ${CMAKE_COMMAND} -E echo "Package created: ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.tar.gz"
    DEPENDS ${PROJECT_NAME}
    COMMENT "Packaging bin and lib directories into tar.gz"
)

# 打印打包使用说明
message(STATUS "")
message(STATUS "Package targets available:")
message(STATUS "  make package_binlib      - Package bin and lib directories")
message(STATUS "")
message(STATUS "FORCE_ARCH usage:")
message(STATUS "  cmake -DFORCE_ARCH=arm .. - Force ARM architecture")
message(STATUS "  cmake -DFORCE_ARCH=x86 .. - Force x86 architecture")
message(STATUS "  cmake ..                  - Auto-detect architecture")
message(STATUS "")